/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "geofence_config.h"

namespace OHOS {
namespace Msdp {
const std::string CONFIG_FILE = "/system/etc/profile/geofence_stats.json";
const double TIME_MINUTE_ENTER_AND_EXIT = 10;
const double TIME_MINUTE_LESS_ONE_KILOMETER = 0;
const double TIME_MINUTE_ONE_TO_TEN_KILOMETERS = 1;
const double TIME_MINUTE_TEN_TO_THIRTY_KILOMETERS = 10;
const double TIME_MINUTE_MORE_THIRTY_KILOMETERS = 30;
const int32_t REPEAT_ENTRY_TIMES = 0;
const double TIMES_ENTER_RADIUS = 1.05;
const double TIMES_EXIT_RADIUS = 1.1;
const int32_t TRACK_TEST_FLAG = 0;

double timeMinuteEnterAndExit_;
double timeMinuteLessOneKm_;
double timeMinuteOneToTenKm_;
double timeMinuteTenToThirtyKm_;
double timeMinuteMoreThirtyKm_;
int32_t repeatEntryTimes_;
double timesEnterRadius_;
double timesExitRadius_;
int32_t trackTestFlag_;


bool GeofenceConfig::Init()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    ParseConfig(CONFIG_FILE);
    return true;
}

double GeofenceConfig::GetTimeMinuteEnterAndExitConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteEnterAndExit_ = %{public}lf", timeMinuteEnterAndExit_);
    return timeMinuteEnterAndExit_;
}

double GeofenceConfig::GetTimeMinuteLessOneKmConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteLessOneKm_ = %{public}lf", timeMinuteLessOneKm_);
    return timeMinuteLessOneKm_;
}

double GeofenceConfig::GetTimeMinuteOneToTenKmConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteOneToTenKm_ = %{public}lf", timeMinuteOneToTenKm_);
    return timeMinuteOneToTenKm_;
}

double GeofenceConfig::GetTimeMinuteTenToThirtyKmConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteTenToThirtyKm_ = %{public}lf", timeMinuteTenToThirtyKm_);
    return timeMinuteTenToThirtyKm_;
}

double GeofenceConfig::GetTimeMinuteMoreThirtyKmConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteMoreThirtyKm_ = %{public}lf", timeMinuteMoreThirtyKm_);
    return timeMinuteMoreThirtyKm_;
}

int32_t GeofenceConfig::GetRepeatEntryTimesConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "repeatEntryTimes_ = %{public}d", repeatEntryTimes_);
    return repeatEntryTimes_;
}

double GeofenceConfig::GetTimesEnterRadiusConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timesEnterRadius_ = %{public}lf", timesEnterRadius_);
    return timesEnterRadius_;
}

double GeofenceConfig::GetTimesExitRadiusConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timesExitRadius_ = %{public}lf", timesExitRadius_);
    return timesExitRadius_;
}

int32_t GeofenceConfig::GetTrackTestFlagConf()
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "trackTestFlag_ = %{public}d", trackTestFlag_);
    return timesExitRadius_;
}

int32_t GeofenceConfig::ParseEnterExitConf(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIME_MINUTE_DISTANCE_FREQUENCY_ENTER_AND_EXIT"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timeMinuteEnterAndExit_ = root["TIME_MINUTE_DISTANCE_FREQUENCY_ENTER_AND_EXIT"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteEnterAndExit_ = %{public}lf", timeMinuteEnterAndExit_);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseLessOneKmConf(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIME_MINUTE_DISTANCE_FREQUENCY_LESS_ONE_KILOMETER"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timeMinuteLessOneKm_ = root["TIME_MINUTE_DISTANCE_FREQUENCY_LESS_ONE_KILOMETER"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteLessOneKm_ = %{public}lf", timeMinuteLessOneKm_);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseOneToTenKmConf(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIME_MINUTE_DISTANCE_FREQUENCY_ONE_TO_TEN_KILOMETERS"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timeMinuteOneToTenKm_ = root["TIME_MINUTE_DISTANCE_FREQUENCY_ONE_TO_TEN_KILOMETERS"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteOneToTenKm_ = %{public}lf", timeMinuteOneToTenKm_);
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseTenToThirtyKmConf(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIME_MINUTE_DISTANCE_FREQUENCY_TEN_TO_THIRTY_KILOMETERS"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timeMinuteTenToThirtyKm_ = root["TIME_MINUTE_TEN_TO_THIRTY_KILOMETERS"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteTenToThirtyKm_ = %{public}lf", timeMinuteTenToThirtyKm_);

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseMoreThirtyKmConf(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIME_MINUTE_DISTANCE_FREQUENCY_MORE_THIRTY_KILOMETERS"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timeMinuteMoreThirtyKm_ = root["TIME_MINUTE_DISTANCE_FREQUENCY_MORE_THIRTY_KILOMETERS"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteMoreThirtyKm_ = %{public}lf", timeMinuteMoreThirtyKm_);

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseRepeatEntryTimes(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["REPEAT_ENTRY_TIMES"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    repeatEntryTimes_ = root["REPEAT_ENTRY_TIMES"].asInt();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "repeatEntryTimes_ = %{public}d", repeatEntryTimes_);

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseEnterTimesRadius(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIMES_ENTER_RADIUS"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timesEnterRadius_ = root["TIMES_ENTER_RADIUS"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timesEnterRadius_ = %{public}lf", timesEnterRadius_);

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseExitTimesRadius(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TIMES_EXIT_RADIUS"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    timesExitRadius_ = root["TIMES_EXIT_RADIUS"].asDouble();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timesExitRadius_ = %{public}lf", timesExitRadius_);

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseTrackTestFlag(Json::Value& root)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    int size = root["TRACK_TEST_FALG"].size();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "size = %{public}d", size);

    trackTestFlag_ = root["TRACK_TEST_FALG"].asInt();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "trackTestFlag_ = %{public}d", trackTestFlag_);

    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}

int32_t GeofenceConfig::ParseConfig(const std::string filename)
{
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "enter");
    Json::Value root;
    Json::CharReaderBuilder readerBuilder;

    std::ifstream geofenceConfig;
    geofenceConfig.open(filename);

    root.clear();
    readerBuilder["collectComments"] = false;
    JSONCPP_STRING errs;

    if (parseFromStream(readerBuilder, geofenceConfig, &root, &errs)) {
        int32_t ret = ParseEnterExitConf(root);
        ret = ParseLessOneKmConf(root);
        ret = ParseOneToTenKmConf(root);
        ret = ParseTenToThirtyKmConf(root);
        ret = ParseMoreThirtyKmConf(root);
        ret = ParseRepeatEntryTimes(root);
        ret = ParseEnterTimesRadius(root);
        ret = ParseExitTimesRadius(root);
        ret = ParseTrackTestFlag(root);
    }else {
        GEOFENCE_HILOGE(GEOFENCE_MODULE_SERVICE, "parse config fail");
        timeMinuteEnterAndExit_ = TIME_MINUTE_ENTER_AND_EXIT;
        timeMinuteLessOneKm_ = TIME_MINUTE_LESS_ONE_KILOMETER;
        timeMinuteOneToTenKm_ = TIME_MINUTE_ONE_TO_TEN_KILOMETERS;
        timeMinuteTenToThirtyKm_ = TIME_MINUTE_TEN_TO_THIRTY_KILOMETERS;
        timeMinuteMoreThirtyKm_ = TIME_MINUTE_MORE_THIRTY_KILOMETERS;
        repeatEntryTimes_ = REPEAT_ENTRY_TIMES;
        timesEnterRadius_ = TIMES_ENTER_RADIUS;
        timesExitRadius_ = TIMES_EXIT_RADIUS;
        trackTestFlag_ = TRACK_TEST_FLAG;
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteEnterAndExit_ = %{public}lf", timeMinuteEnterAndExit_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteLessOneKm_ = %{public}lf", timeMinuteLessOneKm_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteOneToTenKm_ = %{public}lf", timeMinuteOneToTenKm_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteTenToThirtyKm_ = %{public}lf", timeMinuteTenToThirtyKm_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timeMinuteMoreThirtyKm_ = %{public}lf", timeMinuteMoreThirtyKm_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "repeatEntryTimes_ = %{public}d", repeatEntryTimes_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timesEnterRadius_ = %{public}lf", timesEnterRadius_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "timesExitRadius_ = %{public}lf", timesExitRadius_);
        GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "trackTestFlag_ = %{public}d", trackTestFlag_);
    }

    geofenceConfig.close();
    GEOFENCE_HILOGI(GEOFENCE_MODULE_SERVICE, "exit");
    return 1;
}
}  // namespace Msdp
}  // namespace OHOS

